package com.northpool.operator.http.client;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.annotation.OutputParam;
import com.northpool.operator.annotation.OutputParams;
import com.northpool.operator.annotation.ParamEnum;
import com.northpool.operator.annotation.ParamEnums;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.Parameter;
import com.northpool.operator.type.TypeEnum;
import com.northpool.operator.utils.StpOperatorHelper;

import java.util.HashMap;

@OperatorInfo(
    ref = "HttpClientOperator",
    name = "HTTP客户端",
    description = "支持GET/POST等HTTP请求操作",
    enums = {
            @ParamEnums(ref = "method", value = {
                    @ParamEnum(ref = "GET", name = "GET"),
                    @ParamEnum(ref = "POST", name = "POST"),
                    @ParamEnum(ref = "PUT", name = "PUT"),
                    @ParamEnum(ref = "DELETE", name = "DELETE"),
            })
    }
)
@OutputParams({
    @OutputParam(ref = "status", name = "状态码"),
    @OutputParam(ref = "body", name = "响应内容"),
    @OutputParam(ref = "error", name = "错误信息")
})
public class HttpClientOperator extends StpOperatorHelper {

    @InputParams({
        @InputParam(ref = "url", name = "请求地址", desc = "目标访问地址, 如: http://192.168.164.45:8021/gateway/search/query", required = true),
        @InputParam(ref = "method", name = "请求方法", type = TypeEnum.ENUM, required = true, enumRef = "method"),
        @InputParam(ref = "headers", name = "请求头", desc = "多个参数多行隔开，参数名和参数值使用英文冒号(:)隔开", required = false),
        @InputParam(ref = "body", name = "请求体", desc = "请求body参数, 如: {\"keyword\":\"cj97352869\",\"indexs\":[{\"index\":\"apisix\",\"fields\":[\"route_id\"]}]}", required = false),
        @InputParam(ref = "timeout", name = "超时时间(ms)", type = TypeEnum.NUMBER, value = "5000")
    })
    public HttpClientOperator() {
        super();
    }

    public static void main(String[] args) {
        HttpClientOperator client = new HttpClientOperator();
        ParamTool params = ParamTool.aBuilder()
                .add("url", Parameter.Type.STRING.newParameter("http://192.168.164.45:8021/gateway/search/query"))
                .add("method", Parameter.Type.STRING.newParameter("POST"))
                .add("body", Parameter.Type.STRING.newParameter("{\"keyword\":\"cj97352869\",\"indexs\":[{\"index\":\"apisix\",\"fields\":[\"route_id\"]}]}"))
                .add("headers", Parameter.Type.STRING.newParameter("token: 99806919ea9e3846d5fdbfc8470891c4"))
                .add("timeout", Parameter.Type.NUMBER.newParameter("5000"))
                .build();
        client.execute(params);
    }

    @Override
    public void execute(ParamTool params) {
        try {
            String url = params.getStr("url");
            Method method = Method.valueOf(params.getStr("method"));
            String headerStr = params.getStr("headers");
            HashMap<String, String> headers = new HashMap<>();
            Opt.ofBlankAble(headerStr).ifPresent(str -> {
                StrUtil.split(str, "\n").stream()
                        .map(line -> StrUtil.split(line, ':', 2))  // 正确分割键值
                        .filter(arr -> arr.size() == 2)                         // 过滤无效格式
                        .forEach(arr ->
                                headers.put(
                                        arr.get(0).trim(),
                                        arr.get(1).trim()
                                )
                        );
            });

            String requestBody = params.getStr("body");
            int timeout = params.getNumber("timeout").intValue();

            HttpResponse response = HttpUtil.createRequest(method, url)
                .addHeaders(headers)
                .timeout(timeout)
                .body(requestBody)
                .execute();

            handleResponse(response);
        } catch (Exception e) {
            handleError(e);
        }
    }

    private void handleResponse(HttpResponse response) {
        this.result("status", response.getStatus());
        this.result("body", response.body());
        this.result("error", "");
    }

    private void handleError(Exception e) {
        this.result("status", 500);
        this.result("error", ExceptionUtil.getRootCauseMessage(e));
        this.error("请求失败: " + e.getMessage());
    }

}
